package com.ng.common.fileupload.storage;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.UUID;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.ng.common.fileupload.GsFileStorage;
import com.ng.common.fileupload.entity.UploadFileInfoEntity;
import com.ng.common.fileupload.entity.UploadFileInfoEntity.StoreType;
import com.ng.common.utils.StringUtils;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;

/**
 * 七牛云
 * @author lyf
 *
 */
@Component
@ConditionalOnProperty(prefix="ng.upload",name = "type", havingValue = "qiniu")
public class QiNiuStorage implements GsFileStorage{
	
	Logger logger = LoggerFactory.getLogger(getClass());
	
//	String	endpoint = env.getProperty("tr.upload.qiniu.endpoint");// "http://cdn.opgis.com";
//	String	      accessKey = env.getProperty("tr.upload.qiniu.accessKey");// "utP3XunNrYEuJjCMi3TB7ODmHzmWoNzfFUl8A0Kr";
//	String	      secretKey = env.getProperty("tr.upload.qiniu.secretKey");// "_G3PQBcasrAY2TRNQ-UxJeuZO_UHWRqrO6tYmxp-";
//	String	      bucketName = env.getProperty("tr.upload.qiniu.bucketName");// "lyfdemo";

	
	@Value("${ng.upload.qiniu.endpoint}")
    private String endpoint;
	
	@Value("${ng.upload.qiniu.accessKey}")
    private String accessKey;
	
	@Value("${ng.upload.qiniu.secretKey}")
    private String secretKey;
	
	@Value("${ng.upload.qiniu.bucketName}")
    private String bucketName;
    
    
    
    private Auth auth;
    private UploadManager uploadManager;
    private BucketManager bucketManager;
    
    
    

	public String getEndpoint() {
		return endpoint;
	}

	public void setEndpoint(String endpoint) {
		this.endpoint = endpoint;
	}

	public String getAccessKey() {
		return accessKey;
	}

	public void setAccessKey(String accessKey) {
		this.accessKey = accessKey;
	}

	public String getSecretKey() {
		return secretKey;
	}

	public void setSecretKey(String secretKey) {
		this.secretKey = secretKey;
	}

	public String getBucketName() {
		return bucketName;
	}

	public void setBucketName(String bucketName) {
		this.bucketName = bucketName;
	}

	 @Override
	 public String getType() {
		 // TODO Auto-generated method stub
		 return "qiniu";
	 }
	
	@Override
	public UploadFileInfoEntity uploadFile(MultipartFile file) {
		// TODO Auto-generated method stub
		
		InputStream input;
		try {
			input = file.getInputStream();
			
			UploadFileInfoEntity ufe = uploadInputStream(input, file.getSize(), file.getOriginalFilename());
			
			return ufe ;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		 
		return null;
	}
	
	private UploadFileInfoEntity uploadInputStream(InputStream input ,long size , String filename) {
		auth = Auth.create(accessKey, secretKey);
		String upToken = auth.uploadToken(bucketName);
	 	
	
		
		String fileSuffix = StringUtils.getSuffixName(filename);
		
		String key = UUID.randomUUID().toString() + (fileSuffix != null ? "." + fileSuffix : "");
		
		
		if(uploadManager == null) {
			Configuration cfg = new Configuration(Region.region0());
			//...其他参数参考类注释
			uploadManager = new UploadManager(cfg);
		}
		
		try {
			
			byte[] bs = IOUtils.toByteArray(input);
	        
	    	// 2021-09-17 lyf 增加文件格式验证 
			bs = validatorFile(bs, fileSuffix);
			 
			input = new ByteArrayInputStream(bs);
			
		    Response response = uploadManager.put(input, key, upToken,null,null);
		    //解析上传成功的结果
		    DefaultPutRet putRet = JSON.parseObject(response.bodyString(), DefaultPutRet.class)  ;
	 
		    
		    String url = endpoint + "/" + putRet.key;
		    
		    
		    UploadFileInfoEntity ufe = new UploadFileInfoEntity();
		     
		    ufe.setFileSize(size);
		    ufe.setFileUrl(url);
		    ufe.setFileSuffix(fileSuffix);
		    ufe.setStoreType(StoreType.qiniu.getValue());
		    //ufe.setId(putRet.key);
		    ufe.setNewFileName(key);
		    ufe.setOldFileName(filename);
		  
		    
		    return ufe ;
		    
		} catch (QiniuException ex) {
		    Response r = ex.response;
		    System.err.println(r.toString());
		    try {
		        System.err.println(r.bodyString());
		    } catch (QiniuException ex2) {
		        //ignore
		    }
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if(input != null) {
				try {
					input.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
		return null;
	}

	@Override
	public UploadFileInfoEntity uploadFile(File file) {
		InputStream input;
		try {
			input = new FileInputStream(file);
			
			UploadFileInfoEntity ufe = uploadInputStream(input, file.length(), file.getName());
			
			return ufe ;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public void downFile(UploadFileInfoEntity entity, OutputStream out) {
		// TODO Auto-generated method stub
		//String filename = entity.getNewFileName();
		String url = entity.getFileUrl();
		
		URL u;
		try {
			u = new URL(url);
			InputStream input = u.openStream();
			
			org.apache.commons.io.IOUtils.copy(input, out);
			
			out.flush();
			out.close();
			input.close();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		 
	}

	@Override
	public boolean deleteFile(UploadFileInfoEntity entity) {
		if (bucketManager == null) {
			if (auth == null) {
				auth = Auth.create(accessKey, secretKey);
			}
			bucketManager = new BucketManager(auth, new Configuration());
		}
		try {
			Response res = bucketManager.delete(bucketName, entity.getNewFileName());

			return res.isOK();

		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		} 
		return false;
	}
/*
	@Override
	public byte[] readFile(String path) {
		// TODO Auto-generated method stub
		return null;
	}*/

	
	public static void main(String[] args) {
		
		String	endpoint = "http://cdn.opgis.com";
	String	      accessKey = "utP3XunNrYEuJjCMi3TB7ODmHzmWoNzfFUl8A0Kr";
	String	      secretKey = "_G3PQBcasrAY2TRNQ-UxJeuZO_UHWRqrO6tYmxp-";
	String	      bucketName = "lyfdemo";
		
		QiNiuStorage qiniu = new QiNiuStorage();
		qiniu.setAccessKey(accessKey);
		qiniu.setBucketName(bucketName);
		qiniu.setEndpoint(endpoint);
		qiniu.setSecretKey(secretKey);
		
		
		UploadFileInfoEntity  ufe = qiniu.uploadFile(new File("C:\\Users\\lyf\\Pictures\\11.png"));
		
		
		System.out.println(JSON.toJSONString(ufe));
		
	}
	
}
